package azure

import (
	httpUtil "app/pkg/http"
	"encoding/json"
	"fmt"
)

const (
	OutputFormat8k        = "riff-8khz-8bit-mono-alaw"
	OutputFormat8k_8b     = "riff-8khz-8bit-mono-mulaw"
	OutputFormat8k_16b    = "riff-8khz-16bit-mono-pcm"
	OutputFormat2250_16b  = "riff-22050hz-16bit-mono-pcm"
	OutputFormat24k_16b   = "riff-24khz-16bit-mono-pcm"
	OutputFormat44100_16b = "riff-44100hz-16bit-mono-pcm"
	OutputFormat48k_16b   = "riff-48khz-16bit-mono-pcm"
)

var OutputFormatMap = map[string]string{
	"48K": OutputFormat48k_16b,
	"24K": OutputFormat24k_16b,
	"16K": OutputFormat2250_16b,
	"8K":  OutputFormat8k_8b,
}

type Properties struct {
	OutputFormat string `json:"outputFormat"`
	//确定是否生成字边界数据。该可选bool值（“true”或“false”）默认为“false”。 如果请求字边界数据，则相应的[nnnn].word.json文件将包含在结果数据 ZIP 文件中
	WordBoundaryEnabled bool `json:"wordBoundaryEnabled"`
	//确定是否生成句子边界数据。该可选bool值（“true”或“false”）默认为“false”。 如果请求句子边界数据，则[nnnn].sentence.json结果数据 ZIP 文件中将包含相应的文件
	SentenceBoundaryEnabled bool `json:"sentenceBoundaryEnabled"`
	//确定是否连接结果。该可选bool值（“true”或“false”）默认为“false”
	ConcatenateResult bool `json:"concatenateResult"`
	//确定是否将合成结果文件解压到目标容器中。destinationContainerUrl仅当设置了该属性或为语音资源配置了 BYOS（自带存储）时，才能设置此属性。该可选bool值（“true”或“false”）默认为“false”。
	DecompressOutputFiles bool   `json:"decompressOutputFiles"`
	TimeToLive            string `json:"timeToLive"` //P31D
}

type SynthesisClient struct {
	BaseUrl string
	SK      string
}

type Input struct {
	Text string `json:"text"`
}
type SynthesisConfig struct {
	// 音调
	// 作为相对数字：表示为前面带有“+”或“-”、后面带有“Hz”或“st”的数字，指定音高的改变量。例如：<prosody pitch="+80Hz">some text</prosody>或<prosody pitch="-2st">some text</prosody>。
	// “st”表示变化单位是半音，即标准全音阶上的半个音（半音）。
	// 百分比：表示为数字，前面加“+”（可选）或“-”，后面加“%”，表示相对变化。例如：<prosody pitch="50%">some text</prosody>或<prosody pitch="-50%">some text</prosody>
	Pitch string `json:"pitch"`

	// 语速
	// 作为相对数字：表示为充当默认值乘数的数字。例如，值为1不会导致原始速率发生变化。值为0.5会导致原始速率减半。值为2会导致原始速率的两倍。
	// 百分比：表示为数字，前面加“+”（可选）或“-”，后面加“%”，表示相对变化。例如：<prosody rate="50%">some text</prosody>或<prosody rate="-50%">some text</prosody>。
	Rate string `json:"rate"`

	// 指示说话声音的音量级别
	// 绝对值：以 0.0 到 100.0 范围内的数字表示，从最安静到最响亮。例如 75。默认值为 100.0。
	// 相对值：
	// 作为相对数字：表示为前面带有“+”或“-”的数字，指定改变音量的量。例如 +10 或 -5.5。
	// 百分比：表示为数字，前面加“+”（可选）或“-”，后面加“%”，表示相对变化。例如：<prosody volume="50%">some text</prosody>或<prosody volume="+3%">some text</prosody>。
	Volume string `json:"volume"`

	// 调整说话风格来表达不同的情绪
	Style string `json:"style"`

	// 语言
	Voice string `json:"voice"`
}
type BatchSynthesisRequest struct {
	TextType        string          `json:"textType"` //SSML PlainText
	DisplayName     string          `json:"displayName"`
	Description     string          `json:"description"`
	Inputs          []Input         `json:"inputs"`
	Properties      Properties      `json:"properties"`
	SynthesisConfig SynthesisConfig `json:"synthesisConfig"`
}

type BatchSynthesisReply struct {
	TextType           string     `json:"textType"` //SSML PlainText
	DisplayName        string     `json:"displayName"`
	Description        string     `json:"description"`
	Properties         Properties `json:"properties"`
	Status             string     `json:"status"`
	Id                 string     `json:"id"`
	CreatedDateTime    string     `json:"createdDateTime"`
	LastActionDateTime string     `json:"lastActionDateTime"`
}

type BatchSynthesisResultOutputs struct {
	Result string `json:"result"`
}

type BatchSynthesisResult struct {
	Status      string                      `json:"status"`
	TextType    string                      `json:"textType"` //SSML PlainText
	DisplayName string                      `json:"displayName"`
	Id          string                      `json:"id"`
	Outputs     BatchSynthesisResultOutputs `json:"outputs"`
}

type BatchSynthesisZipResult struct {
	WavUrl        string `json:"wavUrl"`
	AudioSize     int64  `json:"audioSize"`
	Duration      string `json:"duration"`
	DurationTicks string `json:"durationTicks"`
}

type SummaryResultProperty struct {
	AudioSize       string `json:"audioSize"`
	Duration        string `json:"duration"`
	DurationInTicks string `json:"durationInTicks"`
}

type SummaryResult struct {
	Text          string                `json:"text"`
	Status        string                `json:"status"`
	AudioFileName string                `json:"audioFileName"`
	Properties    SummaryResultProperty `json:"properties"`
}

type Summary struct {
	JobId   string          `json:"jobID"`
	Status  string          `json:"status"`
	Results []SummaryResult `json:"results"`
}

func NewSynthesisClient() *SynthesisClient {
	return &SynthesisClient{
		BaseUrl: "https://eastasia.customvoice.api.speech.microsoft.com",
		SK:      "57fa473d8db14905814608d9cd280268",
	}
}

func (m *SynthesisClient) defaultHeaders() map[string]string {
	return map[string]string{
		"Ocp-Apim-Subscription-Key": m.SK,
	}
}

// 提交批量合成任务
func (m *SynthesisClient) BatchSynthesis(req BatchSynthesisRequest) (res BatchSynthesisReply, err error) {
	resBytes, err := httpUtil.JsonPost(fmt.Sprintf("%s%s", m.BaseUrl, "/api/texttospeech/3.1-preview1/batchsynthesis"), req, m.defaultHeaders(), 20)
	if err != nil {
		return
	}
	fmt.Println(string(resBytes))
	err = json.Unmarshal(resBytes, &res)
	return
}

// 获取批量合成结果
func (m *SynthesisClient) BatchSynthesisResult(id string) (res BatchSynthesisResult, err error) {
	resBytes, err := httpUtil.Get(fmt.Sprintf("%s%s/%s", m.BaseUrl, "/api/texttospeech/3.1-preview1/batchsynthesis", id), m.defaultHeaders(), 10)
	if err != nil {
		return
	}
	// fmt.Printf("%s", string(resBytes))
	err = json.Unmarshal(resBytes, &res)
	return
}
